package com.wondertek.service.service.business.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wondertek.common.base.Result;
import com.wondertek.common.exception.AppException;
import com.wondertek.common.log.AutoLogUtil;
import com.wondertek.common.util.base.PoiUtil;
import com.wondertek.common.util.security.LoginUser;
import com.wondertek.common.util.security.SecurityUtil;
import com.wondertek.service.dto.app.req.AppDevicePageByUserIdReq;
import com.wondertek.service.dto.app.req.AppRoomUpdateModeReq;
import com.wondertek.service.dto.app.res.AppDeviceNumByUserIdRes;
import com.wondertek.service.dto.app.res.AppDevicePageByUserIdRes;
import com.wondertek.service.dto.business.req.*;
import com.wondertek.service.dto.business.req.NetworkInfoReq;
import com.wondertek.service.dto.business.res.*;
import com.wondertek.service.entity.business.*;
import com.wondertek.service.mapper.business.DeviceMapper;
import com.wondertek.service.mapper.business.SiteMapper;
import com.wondertek.service.sdk.iotdh.dto.Net;
import com.wondertek.service.sdk.iotdh.dto.Power;
import com.wondertek.service.sdk.iotdh.dto.req.*;
import com.wondertek.service.sdk.iotdh.dto.req.network.MobileNetwork;
import com.wondertek.service.sdk.iotdh.dto.req.network.Network;
import com.wondertek.service.sdk.iotdh.dto.req.network.SetMobileNetworkReq;
import com.wondertek.service.sdk.iotdh.dto.req.utc.SetDeviceUTCTimezoneReq;
import com.wondertek.service.sdk.iotdh.dto.res.*;
import com.wondertek.service.sdk.iotdh.dto.res.DevicePageRes;
import com.wondertek.service.sdk.iotdh.dto.res.network.*;
import com.wondertek.service.sdk.iotdh.dto.res.utc.GetDevUTCTimezoneRes;
import com.wondertek.service.sdk.iotdh.service.DhDeviceService;
import com.wondertek.service.service.business.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @description: 设备管理
 * @author: qinjianhui
 * @create: 2024-07-18 10:21
 **/
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, DevicePo> implements DeviceService {

    public List<TimeZoneDictRes> dict = new ArrayList<>();{{
        dict.add(new TimeZoneDictRes("UTC-11:00",32, "InternationalDateLineWest"));
        dict.add(new TimeZoneDictRes("UTC-11:00",31, "UTC-11"));
        dict.add(new TimeZoneDictRes("UTC-10:00",30, "AleutianIslands"));
        dict.add(new TimeZoneDictRes("UTC-09:30",36, "MarquesasIslands"));
        dict.add(new TimeZoneDictRes("UTC-09:00",29, "Alaska"));
        dict.add(new TimeZoneDictRes("UTC-09:00",29, "UTC-09"));
        dict.add(new TimeZoneDictRes("UTC-08:00",28, "LowerCalifornia"));
        dict.add(new TimeZoneDictRes("UTC-08:00",28, "UTC-08"));
        dict.add(new TimeZoneDictRes("UTC-08:00",28, "Pacifictime"));
        dict.add(new TimeZoneDictRes("UTC-07:00",27, "Arizona"));
        dict.add(new TimeZoneDictRes("UTC-07:00",27, "Chihuahua"));
        dict.add(new TimeZoneDictRes("UTC-07:00",27, "Mountaintime"));
        dict.add(new TimeZoneDictRes("UTC-07:00",27, "Yukon"));
        dict.add(new TimeZoneDictRes("UTC-06:00",26, "CentralAmerica"));
    //   dict.add(new TimeZoneDictRes("",26, "Middletime"));
        dict.add(new TimeZoneDictRes("UTC-06:00",26, "EasterIsland"));
        dict.add(new TimeZoneDictRes("UTC-06:00",26, "Guadalajara"));
        dict.add(new TimeZoneDictRes("UTC-06:00",26, "Saskatchewan"));
        dict.add(new TimeZoneDictRes("UTC-05:00",25, "Bogota"));
        dict.add(new TimeZoneDictRes("UTC-05:00",25, "Chetumal"));
        dict.add(new TimeZoneDictRes("UTC-05:00",25, "Easterntime"));
        dict.add(new TimeZoneDictRes("UTC-05:00",25, "Haiti"));
        dict.add(new TimeZoneDictRes("UTC-05:00",25, "Havana"));
        dict.add(new TimeZoneDictRes("UTC-05:00",25, "Indiana"));
        dict.add(new TimeZoneDictRes("UTC-04:00",24, "Asuncion"));
        dict.add(new TimeZoneDictRes("UTC-04:00",24, "Atlantictime"));
        dict.add(new TimeZoneDictRes("UTC-04:00",24, "Caracas"));
        dict.add(new TimeZoneDictRes("UTC-04:00",24, "Cuiaba"));
        dict.add(new TimeZoneDictRes("UTC-04:00",24, "Georgetown"));
        dict.add(new TimeZoneDictRes("UTC-04:00",24, "Santiago"));
        dict.add(new TimeZoneDictRes("UTC-04:00",25, "Turks"));
        dict.add(new TimeZoneDictRes("UTC-03:30",23, "Newfoundland"));
        dict.add(new TimeZoneDictRes("UTC-03:00",22, "Araguaina"));
        dict.add(new TimeZoneDictRes("UTC-03:00",22, "Brasilia"));
        dict.add(new TimeZoneDictRes("UTC-03:00",22, "Cayenne"));
        dict.add(new TimeZoneDictRes("UTC-03:00",22, "BuenosAires"));
        dict.add(new TimeZoneDictRes("UTC-03:00",22, "Greenland"));
        dict.add(new TimeZoneDictRes("UTC-03:00",22, "MondVeeDya"));
        dict.add(new TimeZoneDictRes("UTC-03:00",22, "SaintPierre"));
        dict.add(new TimeZoneDictRes("UTC-03:00",22, "PuntaArenas"));
        dict.add(new TimeZoneDictRes("UTC-03:00",22, "Salvatore"));
        dict.add(new TimeZoneDictRes("UTC-02:00",21, "UTC-02"));
        dict.add(new TimeZoneDictRes("UTC-01:00",20, "Azores"));
        dict.add(new TimeZoneDictRes("UTC-01:00",20, "CaboVerdeIslands"));
        dict.add(new TimeZoneDictRes("UTC+00",0, "UTC-0"));
        dict.add(new TimeZoneDictRes("UTC+01:00",1, "Casablanca"));
        dict.add(new TimeZoneDictRes("UTC+00:00",0, "Dublin"));
        dict.add(new TimeZoneDictRes("UTC+00:00",0, "Monrovia"));
        dict.add(new TimeZoneDictRes("UTC+00:00",0, "SaoTome"));
        dict.add(new TimeZoneDictRes("UTC+01:00",1, "Amsterdam"));
        dict.add(new TimeZoneDictRes("UTC+01:00",1, "Belgrade"));
        dict.add(new TimeZoneDictRes("UTC+01:00",1, "Brussels"));
        dict.add(new TimeZoneDictRes("UTC+01:00",1, "Sarajevo"));
        dict.add(new TimeZoneDictRes("UTC+01:00",1, "CentralandwesternAfrica"));
        dict.add(new TimeZoneDictRes("UTC+02:00",2, "Windhoek"));
        dict.add(new TimeZoneDictRes("UTC+02:00",3, "Amman"));
        dict.add(new TimeZoneDictRes("UTC+02:00",2, "Athens"));
        dict.add(new TimeZoneDictRes("UTC+02:00",2, "Beirut"));
        dict.add(new TimeZoneDictRes("UTC+02:00",2, "Cairo"));
        dict.add(new TimeZoneDictRes("UTC+02:00",2, "Chisinau"));
        dict.add(new TimeZoneDictRes("UTC+02:00",2, "Damascus"));
        dict.add(new TimeZoneDictRes("UTC+02:00",2, "Gaza"));
        dict.add(new TimeZoneDictRes("UTC+02:00",2, "Helsinki"));
        dict.add(new TimeZoneDictRes("UTC+02:00",2, "Jerusalem"));
        dict.add(new TimeZoneDictRes("UTC+02:00",2, "Kaliningrad"));
        dict.add(new TimeZoneDictRes("UTC+02:00",2, "Juba"));
        dict.add(new TimeZoneDictRes("UTC+02:00",2, "Khartoum"));
        dict.add(new TimeZoneDictRes("UTC+02:00",2, "Tripoli"));
        dict.add(new TimeZoneDictRes("UTC+03:00",2, "EasternEurope"));
        dict.add(new TimeZoneDictRes("UTC+03:00",3, "Baghdad"));
        dict.add(new TimeZoneDictRes("UTC+03:00",3, "Istanbul"));
        dict.add(new TimeZoneDictRes("UTC+03:00",3, "Kuwait"));
        dict.add(new TimeZoneDictRes("UTC+03:00",3, "Minsk"));
        dict.add(new TimeZoneDictRes("UTC+03:00",3, "Moscow"));
        dict.add(new TimeZoneDictRes("UTC+03:00",3, "Nairobi"));
        dict.add(new TimeZoneDictRes("UTC+03:30",4, "Tehran"));
        dict.add(new TimeZoneDictRes("UTC+04:00",5, "AbuDhabi"));
        dict.add(new TimeZoneDictRes("UTC+04:00",5, "Astrakhan"));
        dict.add(new TimeZoneDictRes("UTC+04:00",5, "Baku"));
        dict.add(new TimeZoneDictRes("UTC+04:00",5, "Izhevsk"));
        dict.add(new TimeZoneDictRes("UTC+04:00",5, "PortLouis"));
        dict.add(new TimeZoneDictRes("UTC+04:00",5, "Saratov"));
        dict.add(new TimeZoneDictRes("UTC+04:00",5, "Tbilisi"));
        dict.add(new TimeZoneDictRes("UTC+04:00",5, "Yerevan"));
        dict.add(new TimeZoneDictRes("UTC+04:30",6, "Kabul"));
        dict.add(new TimeZoneDictRes("UTC+05:00",7, "Ashkhabad"));
        dict.add(new TimeZoneDictRes("UTC+05:00",7, "Ekaterinburg"));
        dict.add(new TimeZoneDictRes("UTC+05:00",7, "Islamabad"));
        dict.add(new TimeZoneDictRes("UTC+05:00",7, "Qyzylorda"));
        dict.add(new TimeZoneDictRes("UTC+05:30",8, "Chennai"));
        dict.add(new TimeZoneDictRes("UTC+05:30",8, "SriJayawardenapura"));
        dict.add(new TimeZoneDictRes("UTC+05:45",9, "Kathmandu"));
        dict.add(new TimeZoneDictRes("UTC+06:00",10, "Astana"));
        dict.add(new TimeZoneDictRes("UTC+06:00",10, "Dhaka"));
        dict.add(new TimeZoneDictRes("UTC+06:00",10, "Omsk"));
        dict.add(new TimeZoneDictRes("UTC+06:30",11, "Yangon"));
        dict.add(new TimeZoneDictRes("UTC+07:00",12, "Bangkok"));
        dict.add(new TimeZoneDictRes("UTC+07:00",12, "Barnaul"));
        dict.add(new TimeZoneDictRes("UTC+07:00",12, "Hovd"));
        dict.add(new TimeZoneDictRes("UTC+07:00",12, "Krasnoyarsk"));
        dict.add(new TimeZoneDictRes("UTC+07:00",12, "Novosibirsk"));
        dict.add(new TimeZoneDictRes("UTC+07:00",12, "Tomsk"));
        dict.add(new TimeZoneDictRes("UTC+08:00",13, "Beijing"));
        dict.add(new TimeZoneDictRes("UTC+08:00",13, "Irkutsk"));
        dict.add(new TimeZoneDictRes("UTC+08:00",13, "KualaLumpur"));
        dict.add(new TimeZoneDictRes("UTC+08:00",13, "Perth"));
        dict.add(new TimeZoneDictRes("UTC+08:00",13, "Ulaanbaatar"));
        dict.add(new TimeZoneDictRes("UTC+08:30",37, "Pyongyang"));
        dict.add(new TimeZoneDictRes("UTC+08:45",38, "Eucla"));
        dict.add(new TimeZoneDictRes("UTC+09:00",14, "Chita"));
        dict.add(new TimeZoneDictRes("UTC+09:00",14, "Osaka"));
        dict.add(new TimeZoneDictRes("UTC+09:00",14, "Seoul"));
        dict.add(new TimeZoneDictRes("UTC+09:00",14, "Yakutsk"));
        dict.add(new TimeZoneDictRes("UTC+09:30",15, "Adelaide"));
        dict.add(new TimeZoneDictRes("UTC+09:30",15, "Darwin"));
        dict.add(new TimeZoneDictRes("UTC+10:00",16, "Brisbane"));
        dict.add(new TimeZoneDictRes("UTC+10:00",16, "Canberra"));
        dict.add(new TimeZoneDictRes("UTC+10:00",16, "Guam"));
        dict.add(new TimeZoneDictRes("UTC+10:00",16, "Hobart"));
        dict.add(new TimeZoneDictRes("UTC+10:00",16, "Vladivostok"));
        dict.add(new TimeZoneDictRes("UTC+10:30",34, "LordHoweIsland"));
        dict.add(new TimeZoneDictRes("UTC+11:00",17, "BougainvilleIsland"));
        dict.add(new TimeZoneDictRes("UTC+11:00",17, "Chokurdakh"));
        dict.add(new TimeZoneDictRes("UTC+11:00",17, "Magadan"));
        dict.add(new TimeZoneDictRes("UTC+11:00",17, "NorfolkIsland"));
        dict.add(new TimeZoneDictRes("UTC+10:00",17, "Sakhalin"));
        dict.add(new TimeZoneDictRes("UTC+11:00",17, "SolomonIslands"));
        dict.add(new TimeZoneDictRes("UTC+12:00",18, "Anadyr"));
        dict.add(new TimeZoneDictRes("UTC+12:00",18, "Auckland"));
        dict.add(new TimeZoneDictRes("UTC+12:00",18, "UTC+12"));
        dict.add(new TimeZoneDictRes("UTC+12:00",18, "Fiji"));
        dict.add(new TimeZoneDictRes("UTC+12:45",39, "ChathamIslands"));
        dict.add(new TimeZoneDictRes("UTC+13:00",19, "UTC+13"));
        dict.add(new TimeZoneDictRes("UTC+13:00",19, "Nukualofa"));
        dict.add(new TimeZoneDictRes("UTC+13:00",19, "Samoa"));
        dict.add(new TimeZoneDictRes("UTC+14:00",35, "KiritimatiIsland"));
    }}
    @Resource
    private DeviceMapper deviceMapper;

    @Resource
    private DhDeviceService dhDeviceService;

    @Resource
    @Lazy
    private AccessoryService accessoryService;

    @Resource
    @Lazy
    private RoomService roomService;

    @Resource
    private DeviceTypeDetailService deviceTypeDetailService;

    @Resource
    private RentalService rentalService;

    @Resource
    private SiteMapper siteMapper;

    /*
     * 网关设置布防
     * */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void networkSetMode(DeviceNetworkSetModeReq req) {
        //查询设备
        DevicePo devicePo = this.getById(req.getId());
        devicePo.setModeType(req.getModeType());
        this.updateById(devicePo);
        //根据网关查询房间
        LambdaQueryWrapper<RoomPo> roomPoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        roomPoLambdaQueryWrapper.eq(RoomPo::getDeviceId, req.getId());
        List<RoomPo> list = roomService.list(roomPoLambdaQueryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            String modeStr = "";
            //出门-全关-T
            if (1 == req.getModeType()) {
                modeStr = "T";
            } else if (2 == req.getModeType()) {//在家-p1
                modeStr = "p1";
            } else {
                modeStr = "D";//撤防-D
            }
            for (RoomPo roomPo : list) {
                AppRoomUpdateModeReq roomUpdateModeReq = new AppRoomUpdateModeReq();
                roomUpdateModeReq.setRoomId(roomPo.getId());
                roomUpdateModeReq.setMode(modeStr);
                roomService.updateMode(roomUpdateModeReq);
            }
        }
    }

    /*
     * 根据用户ID查询设备数量
     * */
    @Override
    public AppDeviceNumByUserIdRes numByUserId(AppDevicePageByUserIdReq req) {
        AppDeviceNumByUserIdRes appDeviceNumByUserIdRes = new AppDeviceNumByUserIdRes();
        List<AppDevicePageByUserIdRes> list = deviceMapper.pageByUserId(req);
        if (CollectionUtils.isNotEmpty(list)) {
            //获取在线数量
            List<AppDevicePageByUserIdRes> list1 = list.stream().filter(n -> n.getStatus() == 1)
                    .collect(Collectors.toList());
            appDeviceNumByUserIdRes.setOnLineNum(list1.size());
            //获取离线数量
            List<AppDevicePageByUserIdRes> list2 = list.stream().filter(n -> n.getStatus() == 0)
                    .collect(Collectors.toList());
            appDeviceNumByUserIdRes.setOffLineNum(list2.size());
        }
        return appDeviceNumByUserIdRes;
    }

    /*
     * 根据用户ID查询设备
     * */
    @Override
    public PageInfo<AppDevicePageByUserIdRes> pageByUserId(AppDevicePageByUserIdReq req) {
        List<AppDevicePageByUserIdRes> list = deviceMapper.pageByUserId(req);
        if (CollectionUtils.isNotEmpty(list)) {
            for (AppDevicePageByUserIdRes res : list) {
                if (2 == res.getType()) {
                    if (1 == res.getStatus()) {
                        GetStatusReq getStatusReq = new GetStatusReq();
                        getStatusReq.setDeviceId(res.getSnCode());
                        Result<GetStatusRes> statusRes = dhDeviceService.getStatus(getStatusReq);
                        GetStatusRes getStatusRes = statusRes.getData();
                        if (getStatusRes != null) {
                            Net net = getStatusRes.getNet();
                            Power power = getStatusRes.getPower();
                            if (net != null) {
                                res.setWifiIntensity(net.getWirelessNetworkIntensity() != null ? String.valueOf(net.getWirelessNetworkIntensity()) : null);
                            }
                            if (power != null) {
                                res.setBatteryPercent(power.getBatteryPercent());
                            }
                        }
                    } else {
                        res.setWifiIntensity("0");
                        res.setBatteryPercent(0);
                    }
                }
            }
        }
        //根据在线条件筛选数据
        if (req.getStatus() != null) {
            list = list.stream().filter(e -> req.getStatus() == e.getStatus()).collect(Collectors.toList());
        }
        PageInfo pageInfo = new PageInfo<>();
        pageInfo.setPageNum(req.getPageNo());
        pageInfo.setTotal(list.size());
        list = list.subList(req.getPageSize() * (req.getPageNo() - 1),
                req.getPageSize() * req.getPageNo() > list.size() ? list.size() : req.getPageSize() * req.getPageNo());
        pageInfo.setList(list);
        return pageInfo;
    }

    /*
     * 查询未租赁的设备
     * */
    @Override
    public PageInfo<DevicePo> selectNotRentaldevice(DevicePageReq req) {
        PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<DevicePo> list = deviceMapper.selectNotRentaldevice(req);
        PageInfo<DevicePo> poPageInfo = new PageInfo<>(list);
        return poPageInfo;
    }

    /*
     * 新增
     * */
/*    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addDevice(DeviceAddReq deviceAddReq) {
        //暂时只支持设备
        //增加到DH
        DeviceDhAddReq deviceDhAddReq = new DeviceDhAddReq();
        deviceDhAddReq.setDeviceSn(deviceAddReq.getSnCode());
        deviceDhAddReq.setDeviceSkCode(deviceAddReq.getSkCode());
        deviceDhAddReq.setDeviceType(deviceAddReq.getTypeCode());
        deviceDhAddReq.setDeviceSubType(deviceAddReq.getSubTypeCode());
        deviceDhAddReq.setOrgId("1815995641319337985");
        Result<DeviceAddDhRes> deviceAddDhResResult = dhDeviceService.addDevice(deviceDhAddReq);
        DeviceAddDhRes deviceAddDhRes = deviceAddDhResResult.getData();
        if(deviceAddDhRes==null || StringUtils.isBlank(deviceAddDhRes.getDeviceId())){
            throw new AppException("device.add.fail");
        }
        //新增到设备表
        DevicePo devicePo = new DevicePo();
        devicePo.setDeviceCode(deviceAddReq.getDeviceCode());
        devicePo.setDeviceName(deviceAddReq.getDeviceName());
        devicePo.setSnCode(deviceAddReq.getSnCode());
        devicePo.setSkCode(deviceAddReq.getSkCode());
        devicePo.setDeviceTypeId(deviceAddReq.getTypeId());
        devicePo.setIsDelete(0);
        devicePo.setDeviceCode(deviceAddDhRes.getDeviceId());
        this.save(devicePo);
    }*/

    /*
     * 新增-----
     * */
    @Transactional(rollbackFor = Exception.class)
    public void addDevice(DeviceAddReq deviceAddReq) {
        //记录日志
        SitePo sitePo = siteMapper.selectById(deviceAddReq.getSiteId());
        AutoLogUtil.save("sys", "log.device.insert", "设备sn码:" + deviceAddReq.getSnCode(),
                sitePo.getSiteName(), deviceAddReq.getSnCode(), sitePo.getId(), null);
        //暂时只支持设备
        //增加到DH
        DeviceDhAddReq deviceDhAddReq = new DeviceDhAddReq();
        deviceDhAddReq.setDeviceSn(deviceAddReq.getSnCode());
        deviceDhAddReq.setDeviceSkCode(deviceAddReq.getSkCode());
        deviceDhAddReq.setDeviceType(deviceAddReq.getTypeCode());
        deviceDhAddReq.setDeviceSubType(deviceAddReq.getSubTypeCode());
        deviceDhAddReq.setOrgId("1815995641319337985");
        System.out.println("dhreq:" + deviceAddReq);
        Result<DeviceAddDhRes> deviceAddDhResResult = dhDeviceService.addDevice(deviceDhAddReq);
        DeviceAddDhRes deviceAddDhRes = JSONObject.parseObject(String.valueOf(deviceAddDhResResult.getData()), DeviceAddDhRes.class);
        if (deviceAddDhRes == null || StringUtils.isBlank(deviceAddDhRes.getDeviceId())) {
            throw new AppException("device.add.fail");
        }

        final String category = deviceAddReq.getCategory();

        //新增到设备表
        DevicePo devicePo = new DevicePo();
        devicePo.setDeviceCode(deviceAddReq.getDeviceCode());
        devicePo.setDeviceName(deviceAddReq.getDeviceName());
        devicePo.setSnCode(deviceAddReq.getSnCode());
        devicePo.setSkCode(deviceAddReq.getSkCode());
        devicePo.setDeviceTypeId(deviceAddReq.getTypeId());
        devicePo.setSiteId(deviceAddReq.getSiteId());
        devicePo.setIsDelete(0);
        devicePo.setDeviceCode(deviceAddDhRes.getDeviceId());
        devicePo.setStatus(1);
        devicePo.setModeType(2);
        devicePo.setNotAlarmDay(7);
        this.save(devicePo);

        if ("2".equals(category) || "37".equals(deviceAddReq.getTypeId())) {
            //新增网关设备，将配件及已有的分区同步到系统
            GetAreaInfosReq getAreaInfosReq = new GetAreaInfosReq();
            getAreaInfosReq.setDeviceId(deviceAddReq.getSnCode());
            Result<GetAreaInfosRes> areaInfos = dhDeviceService.getAreaInfos(getAreaInfosReq);
            JSONArray a = (JSONArray) JSONObject.parseObject(String.valueOf(areaInfos.getData())).get("areaInfos");
            if (CollectionUtils.isNotEmpty(a)) {
                for (int i = 0; i < a.size(); i++) {
                    JSONObject jsonObject = (JSONObject) a.get(i);
                    JSONArray jsonArray = (JSONArray) jsonObject.get("accessoryInfos");
                    if (0 == i) {
                        //直接增加默认分区
                        String name = (String) jsonObject.get("name");
                        RoomPo roomPo = new RoomPo();
                        roomPo.setRoomName(name);
                        roomPo.setDeviceId(devicePo.getId());
                        roomPo.setRoomCode(1);
                        //查询房间的布防模式
//                        GetAreaInfosReq areaInfosReq = new GetAreaInfosReq();
//                        areaInfosReq.setAreaId(1);
//                        areaInfosReq.setDeviceId(deviceAddReq.getSnCode());
//                        Result<GetAreaArmModeRes> areaArmMode = dhDeviceService.getAreaArmMode(areaInfosReq);
//                        List<ArmModesRes> armModes = JSONArray.parseArray(JSONObject.parseObject(String.valueOf(areaArmMode.getData())).get("armModes").toString(), ArmModesRes.class);
//                        if (CollectionUtils.isNotEmpty(armModes)) {
//                            roomPo.setMode(armModes.get(0).getMode());
//                        }
                        roomPo.setMode("D");
                        roomService.save(roomPo);
                        //把一分区设为撤防才能对后面的房间进行启用
                        AppRoomUpdateModeReq appRoomUpdateModeReq = new AppRoomUpdateModeReq();
                        appRoomUpdateModeReq.setMode("D");
                        appRoomUpdateModeReq.setRoomId(roomPo.getId());
                        roomService.updateMode(appRoomUpdateModeReq);
                        //增加配件
                        if (CollectionUtils.isNotEmpty(jsonArray)) {
                            for (int j = 0; j < jsonArray.size(); j++) {
                                JSONObject accessoryInfo = (JSONObject) jsonArray.get(j);
                                String accessoryCode = (String) accessoryInfo.get("id");
                                String accessoryName = (String) accessoryInfo.get("name");
                                AccessoryPo accessoryPo = new AccessoryPo();
                                accessoryPo.setAccessoryCode(accessoryCode);
                                accessoryPo.setSnCode(accessoryCode);
                                accessoryPo.setAccessoryName(accessoryName);
                                accessoryPo.setRoomId(roomPo.getId());
                                accessoryPo.setIsDelete(0);
                                accessoryPo.setStatus(0);
                                AccessoryPo accessoryPo1 = selectBysnCode(accessoryCode);
                                accessoryPo.setSensorType(accessoryPo1.getSensorType());
                                accessoryPo.setWirelessType(accessoryPo1.getWirelessType());
                                accessoryPo.setModel(accessoryPo1.getModel());
                                accessoryPo.setAccessoryType(accessoryPo1.getAccessoryType());
                                accessoryService.save(accessoryPo);
                            }
                        }
                    } else {
                        if (CollectionUtils.isNotEmpty(jsonArray)) {
                            String name = (String) jsonObject.get("name");
                            RoomPo roomPo = new RoomPo();
                            roomPo.setRoomName(name);
                            roomPo.setDeviceId(devicePo.getId());
                            roomPo.setRoomCode(i + 1);
                            //查询房间的布防模式
//                            GetAreaInfosReq areaInfosReq = new GetAreaInfosReq();
//                            areaInfosReq.setAreaId(i + 1);
//                            areaInfosReq.setDeviceId(deviceAddReq.getSnCode());
//                            Result<GetAreaArmModeRes> areaArmMode = dhDeviceService.getAreaArmMode(areaInfosReq);
//                            List<ArmModesRes> armModes = JSONArray.parseArray(JSONObject.parseObject(String.valueOf(areaArmMode.getData())).get("armModes").toString(), ArmModesRes.class);
//                            if (CollectionUtils.isNotEmpty(armModes)) {
//                                roomPo.setMode(armModes.get(0).getMode());
//                            }
                            roomPo.setMode("D");
                            roomService.save(roomPo);
                            //设为布防
                            AppRoomUpdateModeReq appRoomUpdateModeReq = new AppRoomUpdateModeReq();
                            appRoomUpdateModeReq.setMode("D");
                            appRoomUpdateModeReq.setRoomId(roomPo.getId());
                            roomService.updateMode(appRoomUpdateModeReq);
                            //先去开起分区
                            AetAreaInfoReq aetAreaInfoReq = new AetAreaInfoReq();
                            aetAreaInfoReq.setDeviceId(deviceAddReq.getSnCode());
                            aetAreaInfoReq.setAreaEnable(true);
                            aetAreaInfoReq.setAreaId(i + 1);
                            dhDeviceService.setAreaInfo(aetAreaInfoReq);
                            for (int j = 0; j < jsonArray.size(); j++) {
                                JSONObject accessoryInfo = (JSONObject) jsonArray.get(j);
                                String accessoryCode = (String) accessoryInfo.get("id");
                                String accessoryName = (String) accessoryInfo.get("name");
                                AccessoryPo accessoryPo = new AccessoryPo();
                                accessoryPo.setAccessoryCode(accessoryCode);
                                accessoryPo.setSnCode(accessoryCode);
                                accessoryPo.setAccessoryName(accessoryName);
                                accessoryPo.setRoomId(roomPo.getId());
                                accessoryPo.setIsDelete(0);
                                accessoryPo.setStatus(0);
                                AccessoryPo accessoryPo1 = selectBysnCode(accessoryCode);
                                accessoryPo.setSensorType(accessoryPo1.getSensorType());
                                accessoryPo.setWirelessType(accessoryPo1.getWirelessType());
                                accessoryPo.setModel(accessoryPo1.getModel());
                                accessoryPo.setAccessoryType(accessoryPo1.getAccessoryType());
                                accessoryService.save(accessoryPo);
                            }
                        }
                    }
                }
            }
        }
    }

    /*
     * 根据sn码查询配件
     * */
    public AccessoryPo selectBysnCode(String snCode) {
        List<AccessoryPo> list = accessoryService.selectBysql(snCode);
        AccessoryPo accessoryPo = new AccessoryPo();
        if (CollectionUtils.isNotEmpty(list)) {
            accessoryPo = list.get(0);
        }
        return accessoryPo;
    }

    /*
     * 在新增网关设备时，DH服务默认分区可能添加不及时，异步处理
     * */
    @Async
    protected void addOneRoom(String snCode, String deviceId) {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        Runnable task = () -> {
            RoomPo roomPo = new RoomPo();
            GetAreaInfosReq getAreaInfosReq = new GetAreaInfosReq();
            getAreaInfosReq.setDeviceId(snCode);

            Result<GetAreaInfosRes> areaInfos = dhDeviceService.getAreaInfos(getAreaInfosReq);

            JSONArray a = (JSONArray) JSONObject.parseObject(String.valueOf(areaInfos.getData())).get("areaInfos");
            String name = (String) ((JSONObject) a.get(0)).get("name");
            Integer id = (Integer) ((JSONObject) a.get(0)).get("id");
            roomPo.setRoomName(name);
            roomPo.setDeviceId(deviceId);
            roomPo.setRoomCode(id);
            roomService.save(roomPo);
        };
        // 延迟10秒后执行
        scheduler.schedule(task, 10, TimeUnit.SECONDS);
        scheduler.shutdown();
    }

    /*
     * 删除
     * */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDevice(String id) {
        //记录日志
        DevicePo device = new DevicePo();
        device.setId(id);
        SiteDeviceAccessoryRes res = this.selectSiteDevice(device);
        AutoLogUtil.save("sys", "log.device.delete", "设备sn码:" + res.getDeviceSn(),
                res.getSiteName(), res.getDeviceSn(), res.getSiteId(), null);
        DevicePo po = this.getById(id);
        //检查该设备是否是租赁中
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date();
        String dateStr = simpleDateFormat.format(date);
        LambdaQueryWrapper<RentalDevicePo> rentalLambdaQueryWrapper = new LambdaQueryWrapper<>();
        rentalLambdaQueryWrapper.eq(RentalDevicePo::getDeviceId, id);
        rentalLambdaQueryWrapper.eq(RentalDevicePo::getIsDelete, 0);
        //   rentalLambdaQueryWrapper.apply("start_date < '"+dateStr+"'");
        rentalLambdaQueryWrapper.apply("end_date > '" + dateStr + "'");
        List<RentalDevicePo> list = rentalService.list(rentalLambdaQueryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            throw new AppException("device.is.rental");
        }
        //先查询设备，有则删除DH端设备
        DeviceListReq deviceListReq = new DeviceListReq();
        List<String> deviceIds = new ArrayList<>();
        deviceIds.add(po.getDeviceCode());
        deviceListReq.setDeviceIds(deviceIds);
        Result<DevicePageRes> devicePageResResult = dhDeviceService.pageDevice(deviceListReq);
        DevicePageRes devicePageRes = JSONObject.parseObject(String.valueOf(devicePageResResult.getData()),DevicePageRes.class);
        if(devicePageRes.getTotal()>0){
            DeviceDhDeleteReq req = new DeviceDhDeleteReq();
            req.setDeviceId(po.getDeviceCode());
            dhDeviceService.deleteDevice(req);
        }
        this.removeById(id);
        //检查是不是网关设备，是网关设备要删除下面的房间及配件
        if ("37".equals(po.getDeviceTypeId())) {
            LambdaQueryWrapper<RoomPo> roomPoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roomPoLambdaQueryWrapper.eq(RoomPo::getDeviceId, id);
            List<RoomPo> list1 = roomService.list(roomPoLambdaQueryWrapper);
            if (CollectionUtils.isNotEmpty(list1)) {
                List<String> roomIds = list1.stream().map(RoomPo::getId).collect(Collectors.toList());
                roomService.removeBatchByIds(roomIds);
                LambdaQueryWrapper<AccessoryPo> accessoryPoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                accessoryPoLambdaQueryWrapper.in(AccessoryPo::getRoomId, roomIds);
                List<AccessoryPo> list2 = accessoryService.list(accessoryPoLambdaQueryWrapper);
                if (CollectionUtils.isNotEmpty(list2)) {
                    List<String> accessoryIds = list2.stream().map(AccessoryPo::getId).collect(Collectors.toList());
                    accessoryService.removeBatchByIds(accessoryIds);
                }
            }
        }
    }

    /*
     * 分页查询
     * */
    @Override
    public PageInfo<com.wondertek.service.dto.business.res.DevicePageRes> page(DevicePageReq devicePageReq) {
        //获取登陆用户id
        LoginUser loginUser = SecurityUtil.getLoginUser();
        String userName = loginUser.getName();
        if (!"admin".equals(userName)) {
            String userId = loginUser.getUserId();
            devicePageReq.setUserId(userId);
        }
        List<com.wondertek.service.dto.business.res.DevicePageRes> list = deviceMapper.page(devicePageReq);
        PageInfo pageInfo = new PageInfo<>();
        pageInfo.setTotal(0);
        if (CollectionUtils.isNotEmpty(list)) {
            //根据在线条件筛选数据
            if (devicePageReq.getStatus() != null) {
                list = list.stream().filter(e -> devicePageReq.getStatus() == e.getStatus()).collect(Collectors.toList());
            }
            pageInfo.setTotal(list.size());
            list = list.subList(devicePageReq.getPageSize() * (devicePageReq.getPageNo() - 1),
                    devicePageReq.getPageSize() * devicePageReq.getPageNo() > list.size() ? list.size() : devicePageReq.getPageSize() * devicePageReq.getPageNo());
            pageInfo.setList(list);
        }
        return pageInfo;
    }


    /*
     * 导出设备
     * */
    @Override
    public void exportDevice(DevicePageReq devicePageReq, HttpServletResponse response) {

        devicePageReq.setUserId(null);

        //获取登陆用户id
        LoginUser loginUser = SecurityUtil.getLoginUser();
        String userName = loginUser.getName();
        String userId = "";
        if (!"admin".equals(userName)) {
            userId = loginUser.getUserId();
            devicePageReq.setUserId(userId);
        }

        if (devicePageReq.getIds() != null && !devicePageReq.getIds().isEmpty()) {
            DevicePageReq newReq = new DevicePageReq();
            newReq.setUserId(userId);
            newReq.setIds(devicePageReq.getIds());
            devicePageReq = newReq;
        }

        List<com.wondertek.service.dto.business.res.DevicePageRes> list = deviceMapper.page(devicePageReq);

        List<DeviceExportRes> deviceExportRes = BeanUtil.copyToList(list, DeviceExportRes.class);

        PoiUtil.writeExcelToResponse("设备信息", DeviceExportRes.class, deviceExportRes, response);

    }

    /*
     * 修改
     * */
    @Override
    public void updateDevice(DeviceUpdateReq updateReq) {
        //记录日志
        DevicePo device = new DevicePo();
        device.setId(updateReq.getId());
        SiteDeviceAccessoryRes res = this.selectSiteDevice(device);
        AutoLogUtil.save("sys", "log.device.update", "设备sn码:" + res.getDeviceSn(),
                res.getSiteName(), res.getDeviceSn(), res.getSiteId(), null);
        DevicePo devicePo = new DevicePo();
        devicePo.setId(updateReq.getId());
        devicePo.setDeviceName(updateReq.getDeviceName());
        this.updateById(devicePo);
    }

    /**
     * 根据站点id查询所有网关设备
     *
     * @param siteId
     * @return
     */
    public List<DeviceAllRes> findAllGatewayBySiteId(String siteId) {
        return deviceMapper.findAllGatewayBySiteId(siteId);
    }

    /**
     * 查询所有网关设备
     *
     * @param siteId
     * @return
     */
    public List<DeviceAllRes> findAllGateway(String siteId, String userId) {
        return deviceMapper.findAllGateway(siteId, userId);
    }

    /*
     * 查询站点设备信息
     * */
    public SiteDeviceAccessoryRes selectSiteDevice(DevicePo devicePo) {
        return deviceMapper.selectSiteDevice(devicePo);
    }

    /*
     * 查询站点设备配件信息
     * */
    public SiteDeviceAccessoryRes selectSiteDeviceAccessory(AccessoryPo accessoryPo) {
        return deviceMapper.selectSiteDeviceAccessory(accessoryPo);
    }

    @Override
    public void deviceRestart(String deviceSn) {
        if(deviceMapper.findModeByDeviceSn(deviceSn) > 0)
            throw new AppException("Some areas are armed, can not operate");


        OperateDhReq operateDhReq = new OperateDhReq();
        operateDhReq.setDeviceSn(deviceSn);
        operateDhReq.setOperate("restartDevice");
        operateDhReq.setData(new Object());
        dhDeviceService.operate(operateDhReq);

        //同时将设备下线下线
        LambdaQueryWrapper<DevicePo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(DevicePo::getSnCode,deviceSn);
        List<DevicePo> list = this.list(lambdaQueryWrapper);
        if(CollectionUtils.isNotEmpty(list)){
            DevicePo devicePo = list.get(0);
            devicePo.setStatus(0);
            this.updateById(devicePo);
        }
    }

    @Override
    public List<TimeZoneDictRes> findTimeZoneDict(String search) {


        if(StringUtils.isNotEmpty(search)){

            List<TimeZoneDictRes> res = new ArrayList<>();

            for (TimeZoneDictRes t : dict){
                String areaDesc = t.getAreaDesc();
                if(areaDesc.contains(search))
                    res.add(t);
            }

            return res;
        }

        return dict;
    }

    @Override
    public TimeZoneDictRes findDeviceTimeZone(String deviceSn) {

        ComId comId = new ComId();
        comId.setDeviceId(deviceSn);
        Result<GetDevUTCTimezoneRes> devUTCTimezone = dhDeviceService.getDevUTCTimezone(comId);

        if (devUTCTimezone == null || devUTCTimezone.getData() == null)
            return null;

        String utc = "";
        for (TimeZoneDictRes t : dict){
            String areaDesc = t.getAreaDesc();
            if(devUTCTimezone.getData().getAreaDesc().equals(areaDesc))
                utc = t.getUtc();
        }

        return new TimeZoneDictRes(utc,devUTCTimezone.getData().getTimeZone(), devUTCTimezone.getData().getAreaDesc());
    }

    @Override
    public void setDeviceUTCTimezone(SetDeviceUTCTimezoneReq req) {
        dhDeviceService.setDeviceUTCTimezone(req);
    }

    @Override
    public void modifyDevicePassword(ModifyDevicePasswordReq req) {

        if(deviceMapper.findModeByDeviceSn(req.getDeviceSn()) > 0)
            throw new AppException("Some areas are armed, can not operate");

        ModifyDevCodeReq modifyDevCodeReq = new ModifyDevCodeReq();
        modifyDevCodeReq.setDeviceId(req.getDeviceSn());
        modifyDevCodeReq.setOldDevCode(req.getOldDevCode());
        modifyDevCodeReq.setNewDevCode(req.getNewDevCode());
        dhDeviceService.modifyDevCode(modifyDevCodeReq);
    }

    @Override
    public void setNetworkInfo(NetworkInfoReq networkInfoReq) {

        SetNetworkInfoReq setNetworkInfoReq = new SetNetworkInfoReq();

        setNetworkInfoReq.setDeviceId(networkInfoReq.getDeviceSn());

        Network network = new Network();
        network.setIpAddress(networkInfoReq.getIpAddress());
        network.setSubNetworkMask(networkInfoReq.getSubNetworkMask());
        network.setDefaultGateway(networkInfoReq.getDefaultGateway());
        network.setDnsServers(networkInfoReq.getDns());
        network.setPhysicalAddress(networkInfoReq.getPhysicalAddress());
        network.setDhcpEnable(networkInfoReq.isDhcpEnable());


        setNetworkInfoReq.setNetworks(new ArrayList<>() {{
            add(network);
        }});

        dhDeviceService.setNetworkInfo(setNetworkInfoReq);
    }

    @Override
    public NetworkInfoReq findNetworkInfo(String deviceSn) {

        ComId comId = new ComId();
        comId.setDeviceId(deviceSn);

        Result<GetNetworkInfoRes> networkInfo = dhDeviceService.getNetworkInfo(comId);

        if (networkInfo == null || networkInfo.getData() == null)
            return null;

        List<com.wondertek.service.sdk.iotdh.dto.res.network.Network> networks = networkInfo.getData().getNetworks();

        NetworkInfoReq networkInfoReq = new NetworkInfoReq();

        networkInfoReq.setDeviceSn(deviceSn);

        if (networks != null && !networks.isEmpty()) {
            com.wondertek.service.sdk.iotdh.dto.res.network.Network network = networks.get(0);
            networkInfoReq.setIpAddress(network.getIpAddress());
            networkInfoReq.setSubNetworkMask(network.getSubNetworkMask());
            networkInfoReq.setDefaultGateway(network.getDefaultGateway());
            networkInfoReq.setDns(network.getDnsServers());
            networkInfoReq.setPhysicalAddress(network.getPhysicalAddress());
            networkInfoReq.setDhcpEnable(network.getDhcpEnable());
        }


        return networkInfoReq;
    }

    @Override
    public GetCurrentWirelessNetworkRes findUseWifi(String deviceSn) {
        ComId comId = new ComId();
        comId.setDeviceId(deviceSn);
        Result<GetCurrentWirelessNetworkRes> currentWirelessNetwork = dhDeviceService.getCurrentWirelessNetwork(comId);

        return currentWirelessNetwork == null ? null : currentWirelessNetwork.getData();
    }

    @Override
    public List<AroundWirelessNetwork> findNearbyWifi(String deviceSn) {
        ComId comId = new ComId();
        comId.setDeviceId(deviceSn);
        Result<GetAroundWirelessNetworkInfosRes> aroundWirelessNetworkInfos = dhDeviceService.getAroundWirelessNetworkInfos(comId);
        return (aroundWirelessNetworkInfos == null || aroundWirelessNetworkInfos.getData() == null) ? null : aroundWirelessNetworkInfos.getData().getAroundWirelessNetworks();
    }

    @Override
    public void connectWifi(ModifyWirelessNetwork modifyWirelessNetwork) {

      //  try {
            dhDeviceService.modifyWirelessNetwork(modifyWirelessNetwork);
    /*    } catch (Exception e) {
            throw new AppException("Password error");
        }*/


    }

    @Override
    public void setCellularNetwork(String deviceSn, boolean status) {

        SetMobileNetworkReq setMobileNetworkReq = new SetMobileNetworkReq();
        setMobileNetworkReq.setDeviceId(deviceSn);

        List<MobileNetwork> objects = new ArrayList<>(){{
            MobileNetwork mobileNetwork = new MobileNetwork();
            mobileNetwork.setActivate(status);
            add(mobileNetwork);
        }};

        setMobileNetworkReq.setMobileNetworks(objects);

        dhDeviceService.setMobileNetwork(setMobileNetworkReq);
    }

    @Override
    public boolean findCellularNetwork(String deviceSn) {

        ComId comId = new ComId();
        comId.setDeviceId(deviceSn);
        Result<List<GetMobileNetworkInfoRes>> mobileNetworkInfo = dhDeviceService.getMobileNetworkInfo(comId);

        if(mobileNetworkInfo == null || mobileNetworkInfo.getData() == null || mobileNetworkInfo.getData().isEmpty())
            return false;


        return mobileNetworkInfo.getData().get(0).isActivate();
    }

    @Override
    public AccessoryStatusDetectionSumReq findAccessoryStatus(String deviceSn, Integer pageNo, Integer pageSize) {

        GetAccessoryInfoReq getAccessoryInfoReq = new GetAccessoryInfoReq();
        getAccessoryInfoReq.setDeviceId(deviceSn);
        Result<List<GetAccessoryStatusRes>> accessoryStatus = dhDeviceService.getAccessoryStatus(getAccessoryInfoReq);

        if (accessoryStatus == null || accessoryStatus.getData() == null || accessoryStatus.getData().isEmpty())
            return null;

        List<GetAccessoryStatusRes> data = accessoryStatus.getData();

        int accessorySum = 0;

        int onlineSum = 0;

        int offlineSum = 0;

        for (GetAccessoryStatusRes g : data){
            accessorySum++;

            if(g.getOnline() == 2) // 在线
                onlineSum++;
            else
                offlineSum++;
        }

        PageInfo pageInfo = new PageInfo<>();
        pageInfo.setPageNum(pageNo);
        pageInfo.setTotal(pageSize);
        data = data.subList(pageSize * (pageNo - 1),
                pageSize * pageNo > data.size() ? data.size() : pageSize * pageNo);


        Map<String,Integer> map = new HashMap<>();
        List<String> sn = new ArrayList<>();

        for (GetAccessoryStatusRes g : data){
            map.put(g.getId(),g.getOnline());
            sn.add(g.getId());
        }

        List<AccessoryStatusDetectionReq> accessoryStatusDetectionReqs = deviceMapper.accessoryStatusDetection(sn);

        for (AccessoryStatusDetectionReq a : accessoryStatusDetectionReqs){
            Integer i = map.get(a.getSnCode());
            a.setStatus(map.get(a.getSnCode()) == 2 ? "online" : "offline");
        }


        pageInfo.setList(accessoryStatusDetectionReqs);

        AccessoryStatusDetectionSumReq accessoryStatusDetectionSumReq = new AccessoryStatusDetectionSumReq();

        accessoryStatusDetectionSumReq.setAccessorySum(accessorySum);
        accessoryStatusDetectionSumReq.setOnlineSum(onlineSum);
        accessoryStatusDetectionSumReq.setOfflineSum(offlineSum);
        accessoryStatusDetectionSumReq.setList(pageInfo);

        return accessoryStatusDetectionSumReq;
    }

    @Override
    public Integer findModeByDeviceSn(String deviceSn) {
        return deviceMapper.findModeByDeviceSn(deviceSn);
    }


}

